//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/*
  Boot loader command
    help
    boot arg0 arg1
    dn filename address(default : 0xc0000000)
    tftp filename address(default : 0xc0000000)
    flash dest_address source_address length
    bl_flash source_address length
    dump address length
    memset address value length
    jump address
    gpioset value
    gpiord
    ram_test start_address length(Mbytes)
    net_test
    script address
*/

# include "config.h"

#include "command.h"
#include "serial.h"
#include "time.h"
#include "types.h"
#include "util.h"
#include "tat.h"

/* display a prompt, or the standard prompt if prompt == NULL */
void DisplayPrompt(char *prompt)
{
    if (prompt == NULL) {
        if (verbose_level > 0)
            printk("\nBlob> ");
    }
    else {
        if (verbose_level > 0)
            printk("%s", prompt);
    }
}

/* more or less like SerialInputString(), but with echo and backspace  */
int GetCommand(char *command, int len, int timeout)
{
    u32 startTime, currentTime;
    char c;
    int i;
    int numRead;
    int maxRead = len - 1;

    startTime = TimerGetTime();

    for (numRead = 0, i = 0; numRead < maxRead;) {
        /* try to get a byte from the serial port */
        while (!SerialInputByte(&c)) {
            currentTime = TimerGetTime();

            /* check timeout value */
            if ((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) {
                /* timeout */
                command[i++] = '\0';
                return(numRead);
            }
        }

        if ((c == '\r') || (c == '\n')) {
            if (i == 0) {
                if (verbose_level > 0)
                    printk("\n");
                DisplayPrompt("Eldr>");
                numRead = 0;
            }
            else {
                command[i++] = '\0';
                /* print newline */
                if (verbose_level > 0)
                    printk("\n");
                return(numRead);
            }
        }
        else if (c == '\b') { /* FIXME: is this backspace? */
            if (i > 0) {
                i--;
                numRead--;
                    /* cursor one position back. */
                if (verbose_level > 0)
                    printk("\b \b");
            }
        }
        else {
            command[i++] = c;
            numRead++;

            /* print character */
            if (verbose_level > 0)
                printk("%c", c);
        }
    }

    return(numRead);
}

/*
  Parse a file name from the input command
*/
int ParseFileName(u8* InputCommand, int* NextReadLocation, u8* FileName)
{
    int i=0;
    int StartLocation;

    while((InputCommand[i]==' ')||(InputCommand[i]=='\t')) i++; /* skips the preceeding blanks */
    StartLocation = i;
    while ((InputCommand[i] != ' ') && (InputCommand[i] != '\t') && (InputCommand[i] != '\0') && (InputCommand[i] != '\r') && (InputCommand[i] != '\n')) {
        FileName[i-StartLocation]=InputCommand[i];
        i++;
    }
    if((i==StartLocation)||(InputCommand[StartLocation]=='\0')) return 0; /* no filename */
    FileName[i-StartLocation]='\0';
    (*NextReadLocation) = i;

    return 1;
}

/*
  return -1 when there's error in the input
          0 when there's no input number
          1 when ok
*/
int ParseNumber(u8* InputCommand, int* NextReadLocation, u32* ReadValue)
{
    int i=0;
    u32 ValuePerDigit = 10;
    u32 Input = 0;
    int StartLocation;

    while((InputCommand[i]==' ')||(InputCommand[i]=='\t')) i++; /* skips the preceeding blanks */
    StartLocation = i;
    if (MyStrCmp(InputCommand + i, "0x", 2)) { /* hexa mode */
        ValuePerDigit = 0x10;
        i+=2;
    }

    while ((InputCommand[i] != ' ') && (InputCommand[i] != '\t') && (InputCommand[i] != '\0') && (InputCommand[i] != '\r') && (InputCommand[i] != '\n')) {
        if ((InputCommand[i] >= '0') && (InputCommand[i] <= '9')) { /* normal digit */
            Input*= ValuePerDigit;
            Input += (InputCommand[i]-'0');
        }
        else if ((InputCommand[i] >= 'a') && (InputCommand[i] <= 'f')) { /* hexadecimal */
            Input*= ValuePerDigit;
            Input += (InputCommand[i]-'a'+10);
        }
        else if ((InputCommand[i] >= 'A') && (InputCommand[i] <= 'F')) { /* hexadecimal */
            Input*= ValuePerDigit;
            Input += (InputCommand[i]-'A'+10);
        }
        else {
            printk("Error : unrecognized number in %s \n", InputCommand);
            return -1;
        }
        i++;
    }

    if((i==StartLocation)||(InputCommand[StartLocation]=='\0')) return 0; /* no number */
    (*NextReadLocation) = i;
    (*ReadValue) = Input;
    return 1;
}
